﻿// Copyright © Armen Kirakosyan
// armen@kirakosyan.com

namespace Validator
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.IO;
    using System.Text;

    /// <summary>
    /// Used for W3C SOAP Response parsing 
    /// SOAP 1.2 response format reference
    /// http://validator.w3.org/docs/api.html
    /// </summary>
    public class ValidatorResult
    {
        /// <summary>
        /// The main element of the validation response. Encloses all other information about the validation results
        /// </summary>
        public string MarkupValidationResponse;

        /// <summary>
        /// The address of the document validated
        /// </summary>
        public string Url;

        /// <summary>
        /// Location of the service which provided the validation result
        /// </summary>
        public string CheckedBy;

        /// <summary>
        /// Detected (or forced) Document Type for the validated document
        /// </summary>
        public string DocType;

        /// <summary>
        /// Detected (or forced) Character Encoding for the validated document
        /// </summary>
        public string Charset;

        /// <summary>
        /// Whether or not the document validated passed or not formal validation
        /// </summary>
        public bool Validity;

        /// <summary>
        /// Encapsulates all data about errors encountered through the validation process
        /// </summary>
        public List<ValidationError> Errors;

        /// <summary>
        /// a child of errors, counts the number of errors listed
        /// </summary>
        public int ErrorCount { get { return Errors.Count; } }

        public ValidatorResult(string xml)
        {
            MarkupValidationResponse = xml;
            Errors = new List<ValidationError>();
            var ds = new DataSet();

            using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
            {
                ds.ReadXml(ms);
                ms.Close();
            }

            // in 9th table error description
            if (ds.Tables.Count == 9)
            {
                throw new ArgumentException(ds.Tables[8].Rows[0][1].ToString()); 
            }

            // Read gen, Table #1
            Url       = ds.Tables[1].Rows[0]["uri"].ToString();
            CheckedBy = ds.Tables[1].Rows[0]["checkedby"].ToString();
            DocType   = ds.Tables[1].Rows[0]["doctype"].ToString();
            Charset   = ds.Tables[1].Rows[0]["charset"].ToString();
            Validity  = bool.Parse(ds.Tables[1].Rows[0]["Validity"].ToString());

            //Read Errors table #4
            // if Valid there is no Errors table
            if (!Validity)
            {
                foreach (DataRow row in ds.Tables[4].Rows)
                {
                    var error = new ValidationError
                    {
                        Line = row["line"].ToString(),
                        Col  = row["col"].ToString(),

                        Message     = row["message"].ToString(),
                        MessageId   = row["messageid"].ToString(),
                        Explanation = row["explanation"].ToString(),
                        Source      = row["source"].ToString()
                    };

                    Errors.Add(error);
                }
            }
        }
    }
}
